package com.smasher.location.actual;

import android.Manifest;
import android.content.Context;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresPermission;

import com.smasher.location.listener.LocationCallback;
import com.smasher.location.proxy.LocationNa;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;

public class LocationNative implements LocationNa {

    public static final String TAG = "LocationNative";

    private LocationManager locationManager;
    private LocationCallback mCallback;

    private boolean started = false;
    private Geocoder geocoder;

    @Override
    public void init(Context context) {
        locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        geocoder = new Geocoder(context, Locale.getDefault());
        if (locationManager != null) {
            // 获取所有可用的位置提供器
            List<String> providerList = locationManager.getProviders(true);
            // 可以指定优先GPS，再次网络定位
            if (providerList.contains(LocationManager.GPS_PROVIDER)) {
                String providerGps = LocationManager.GPS_PROVIDER;
                Log.i(TAG, "providerGps: " + providerGps);
            } else if (providerList.contains(LocationManager.NETWORK_PROVIDER)) {
                String providerNetwork = LocationManager.NETWORK_PROVIDER;
                Log.i(TAG, "providerNetwork: " + providerNetwork);
            } else {
                // 当没有可用的位置提供器时，弹出Toast提示用户
                Log.i(TAG, "init: ");
            }
        }

    }

    @Override
    public void setCallback(LocationCallback callback) {
        mCallback = callback;
    }

    @RequiresPermission(allOf = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION})
    @Override
    public void start() {
        Log.i(TAG, "start: ");
        Criteria criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_COARSE);
        criteria.setAltitudeRequired(false);//不要求海拔
        criteria.setBearingRequired(false);//不要求方位
        criteria.setCostAllowed(true);//允许有花费
        criteria.setPowerRequirement(Criteria.POWER_LOW);//低功耗

        if (locationManager == null) {
            Log.e(TAG, "locationManager is null");
            if (mCallback != null) {
                mCallback.onFailed("没有可用的位置提供器");
            }
        } else {
            String provider = locationManager.getBestProvider(criteria, true);
            if (provider != null) {
                Location location = locationManager.getLastKnownLocation(provider);
                if (location != null) {
                    //不为空,显示地理位置经纬度
                    String longitude = "Longitude:" + location.getLongitude();
                    Log.i(TAG, "longitude: " + longitude);
                    String latitude = "Latitude:" + location.getLatitude();
                    Log.i(TAG, "Latitude: " + latitude);
                    long time = location.getTime();
                    SimpleDateFormat format =
                            new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
                    Log.i(TAG, "time: " + format.format(new Date(time)));

                    String address = getAddressFromLatLong(
                            location.getLatitude(), location.getLongitude());
                    Log.i(TAG, "address: " + address);
                    long current = System.currentTimeMillis();
                    if (current - time > 1000 * 60 * 10) {
                        Log.i(TAG, "LastKnownLocation is out of time");
                        Log.i(TAG, "provider " + provider + " starting ");
                        //第二个参数是间隔时间 第三个参数是间隔多少距离，这里我试过了不同的各种组合，能获取到位置就是能，不能获取就是不能
                        locationManager.requestSingleUpdate(provider, locationListener, null);
                    } else {
                        if (mCallback != null) {
                            mCallback.onSuccess(longitude + "," + latitude, address);
                        }
                    }
                } else {
                    Log.i(TAG, "LastKnownLocation is null");
                    Log.i(TAG, "provider " + provider + " starting ");
                    //第二个参数是间隔时间 第三个参数是间隔多少距离，这里我试过了不同的各种组合，能获取到位置就是能，不能获取就是不能
                    locationManager.requestSingleUpdate(provider, locationListener, null);
                    started = true;
                }


            } else {
                Log.e(TAG, "provider is null");
                if (mCallback != null) {
                    mCallback.onFailed("没有可用的位置提供器");
                }
            }
        }

    }

    @Override
    public void stop() {
        if (locationManager != null && started) {
            started = false;
            locationManager.removeUpdates(locationListener);
        }
    }

    @Override
    public void release() {

    }

    private final LocationListener locationListener = new LocationListener() {

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            //LocationProvider#OUT_OF_SERVICE：无服务
            //LocationProvider#TEMPORARILY_UNAVAILABLE：provider不可用
            //LocationProvider#AVAILABLE：provider可用
            switch (status) {
                case LocationProvider.AVAILABLE:
                    Log.i(TAG, "onStatusChanged: LocationProvider.AVAILABLE");
                    break;
                case LocationProvider.TEMPORARILY_UNAVAILABLE:
                    Log.i(TAG, "onStatusChanged: LocationProvider.TEMPORARILY_UNAVAILABLE");
                    break;
                case LocationProvider.OUT_OF_SERVICE:
                    Log.i(TAG, "onStatusChanged: LocationProvider.OUT_OF_SERVICE");
                    break;
                default:
                    Log.i(TAG, "onStatusChanged: Default");
                    break;
            }
        }

        @Override
        public void onLocationChanged(@NonNull Location location) {
            Log.i(TAG, "onLocationChanged: " + location);
            String address = getAddressFromLatLong(
                    location.getLatitude(), location.getLongitude());
            Log.i(TAG, "address: " + address);
            String longitude = "Longitude:" + location.getLongitude();
            Log.i(TAG, "longitude: " + longitude);
            String latitude = "Latitude:" + location.getLatitude();
            Log.i(TAG, "Latitude: " + latitude);
            if (mCallback != null) {
                mCallback.onSuccess(longitude + "," + latitude, address);
            }
        }

        @Override
        public void onProviderEnabled(@NonNull String provider) {
            Log.d(TAG, "onProviderEnabled: " + provider);
        }

        @Override
        public void onProviderDisabled(@NonNull String provider) {
            Log.d(TAG, "onProviderDisabled: " + provider);
            if (mCallback != null) {
                mCallback.onFailed(provider + "位置提供器不可用");
            }
        }
    };

    public String getAddressFromLatLong(double latitude, double longitude) {
        try {
            if (geocoder != null) {
                List<Address> addresses = geocoder.getFromLocation(latitude, longitude, 1);
                if (addresses != null && !addresses.isEmpty()) {
                    Log.i(TAG, "address count: " + addresses.size());
                    for (Address address : addresses) {
                        Log.d(TAG, "address: " + address.getAddressLine(0));
                    }
                    Address address = addresses.get(0);
                    // 获取地址信息
                    return address.getAddressLine(0);
                }
            }
        } catch (IOException e) {
            Log.e(TAG, "getAddressFromLatLong: ", e);
        }
        return null;
    }
}
